//  On my honor:
//	
//  - I have not used source code obtained from another student, 
//    or any other unauthorized source, either modified or unmodified.  
//	
//  - All source code and documentation used in my program 
//    is either my original work, or was derived by me from the source
//    code published in the textbook for this course.
//	
//  - I have not discussed coding details about this project with anyone
//    other than my instructor, ACM/UPE tutors or the GTAs assigned to this
//    course. I understand that I may discuss the concepts of this program
//    with other students, and that another student may help me debug my
//    program so long as neither of us writes anything during the discussion
//    or modifies any computer file during the discussion.  I have violated
//    neither the spirit nor letter of this restriction.
//	

/**
 * @author Christopher Suh, Eric Yoo
 * 
 */
import java.util.ArrayList;

public class MemManager {
	private BTree<String, City> bst;
	private PRQuadTree<City> qt;

	/** Constructor */
	MemManager() {
		bst = new BTree<String, City>(new StringComparator());
		qt = new PRQuadTree<City>(0, 16384, 0, 16384);
	}

	public boolean insert(int x, int y, String name) {
		if (x < 0 || x >= 16384) {
			System.out.println("Insert rejected, bad X coordinate");
			System.out.flush();
			return false;
		} else if (y < 0 || y >= 16384) {
			System.out.println("Insert rejected, bad Y coordinate");
			System.out.flush();
			return false;
		} else {
			City c = new City(name, x, y);
			// attempt to insert to quadtree
			if (qt.insert(c, x, y)) {
				// insert to BST if insert to quadtree was successful
				bst.insert(name, c);
				System.out.println("Insert operation successful");
				System.out.flush();
				return true;
			} else {
				System.out
						.println("Insert rejected, coordinates duplicate an existing city record");
				System.out.flush();
				return false;
			}
		}
	}

	public City remove(int x, int y) {
		if (x < 0 || x >= 16384) {
			System.out.println("Remove rejected, bad X coordinate");
			System.out.flush();
			return null;
		} else if (y < 0 || y >= 16384) {
			System.out.println("Remove rejected, bad Y coordinate");
			System.out.flush();
			return null;
		} else {
			// attempt to remove from quadtree to make sure the city exists in
			// the database
			City temp = qt.remove(x, y);
			if (temp != null) {
				// remove from BST if first remove was successful
				bst.remove(temp.name(), temp);
				System.out.println("Removed " + temp);
				System.out.flush();
			} else {
				System.out.println("No such City record found");
				System.out.flush();
			}
			return temp;
		}
	}

	public City remove(String name) {
		// first, remove from bst to make sure the city exists in the
		// database
		City temp = bst.remove(name);
		if (temp != null) {
			// remove from quad tree if non null value is returned
			qt.remove(temp.xCoor(), temp.yCoor());
			System.out.println("Removed " + temp);
			System.out.flush();
		} else {
			System.out.println("No such City record found");
			System.out.flush();
		}
		return temp;
	}

	public void find(String name) {
		ArrayList<City> list = bst.findAll(name);
		System.out.println("City Records found:");
		System.out.flush();
		if (list == null) {
			System.out.println("No records");
			System.out.flush();
		} else
			for (City c : list) {
				System.out.println(c);
				System.out.flush();
			}
		System.out.flush();
	}

	public void search(int x, int y, int radius) {
		if(x < -16384 || x >= 16384)
		{
			System.out.println("Search operation failed: Bad X coordinate");
			System.out.flush();
		}
		else if(y < -16384 || y >= 16384)
		{
			System.out.println("Search operation failed: Bad Y coordinate");
			System.out.flush();
		}
		else if(radius < 0 || radius >= 16384)
		{
			System.out.println("Search operation failed: Bad Radius value");
			System.out.flush();
		}
		else
		{
			System.out.println("City Record(s) found:");
			int trav = qt.search(x, y, radius);
			System.out.println("" + trav + " nodes visited");
		}
	}

	public void debug() {
		qt.debug();
	}

	public void makenull() {
		bst = new BTree<String, City>(new StringComparator());
		qt = new PRQuadTree<City>(0, 16384, 0, 16384);
		System.out.println("Makenull operation successful");
		System.out.flush();
	}
}
